#include "app_measure.h"

GD_DATA_TYPE GdData;

static const uint8_t GD_LOGIC_TABLE_0_2_X[] =
{0x0A, 0x25, 0x27, 0x08, 0x23, 0x06, 0x17, 0x07, 0x29, 0x19, 0x00, 0x09, 0x13, 0x16, 0x10, 0x26, 0x21, 0x15, 0x11, 0x18, 0x04, 0x05, 0x14, 0x24, 0x02, 0x12, 0x01, 0x28, 0x03, 0x22, 0x20, 0x1A};

static const uint8_t GD_LOGIC_TABLE_1_3_X[] =
{0x0A, 0x24, 0x26, 0x07, 0x28, 0x18, 0x09, 0x08, 0x22, 0x05, 0x16, 0x06, 0x12, 0x15, 0x19, 0x25, 0x20, 0x14, 0x10, 0x17, 0x01, 0x11, 0x00, 0x27, 0x03, 0x04, 0x13, 0x23, 0x02, 0x21, 0x29, 0x1A};


void GD_Measure_Init(void)
{
	BSP_ADC_init();
	BSP_GDLED_PORT_init();
}

/*
************************************************************************
*	函数名: GdGetAdc
*	形   参：void
*	返回值: void
*	说   明: 获取光电读数的核心接口
************************************************************************
*/
static void GdGetAdc(void)
{
	memset(&GdData, 0, sizeof(GdData));
	GD_RecvLED_Enable;
	BSP_ADC_Enable();
	
	DelayMs(GD_DELAY_LED_WAIT);
	DelayMs(GD_DELAY_LED_WAIT);
	
	GdData.AdcDataRxLedOff[0] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_0)>>4;
	GdData.AdcDataRxLedOff[1] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_1_2)>>4;
	GdData.AdcDataRxLedOff[2] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_1_2)>>4;
	GdData.AdcDataRxLedOff[3] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_3)>>4;
	
	for (uint8_t i=0; i<(GD_WHEEL_COUNT>>1); i++)
	{
		for (uint8_t j=0; j<GD_LED_COUNT_PER_WHEEL; j++)
		{
			switch (j)
			{
				case 0: GD_enable_led_0(); break;
				case 1: GD_enable_led_1(); break;
				case 2: GD_enable_led_2(); break;
				case 3: GD_enable_led_3(); break;
				case 4: GD_enable_led_4(); break;
			}
			switch (i)
			{
				case 0:
				{
					GD_enable_wheel_0_1();
					DelayMs(GD_DELAY_LED_WAIT);
					GdData.AdcDataTxLed[0][j] = BSP_ADC_Read(GD_ADC_CHANNEL_TX_0_1)>>4;
					GdData.AdcDataRxLedOn[0][j] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_0)>>4;
					GdData.AdcDataRxLedOn[1][j] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_1_2)>>4;
					break;
				}
				case 1:
				{
					GD_enable_wheel_2_3();
					DelayMs(GD_DELAY_LED_WAIT);
					GdData.AdcDataTxLed[1][j] = BSP_ADC_Read(GD_ADC_CHANNEL_TX_2_3)>>4;
					GdData.AdcDataRxLedOn[2][j] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_1_2)>>4;
					GdData.AdcDataRxLedOn[3][j] = BSP_ADC_Read(GD_ADC_CHANNEL_RX_3)>>4;
					break;
				}
			}
			GD_SendLED_Disable;	
			DelayMs(GD_DELAY_LED_WAIT);
		}
	}
	
	BSP_ADC_Disable();
	GD_RecvLED_Disable;
	
	for (uint8_t i=0; i<(GD_WHEEL_COUNT>>1); i++)
	{
		for (uint8_t j=0; j<GD_LED_COUNT_PER_WHEEL; j++)
		{
			if ((GdData.AdcDataTxLed[i][j] < GD_ADC_TX_MIN)||\
                 (GD_ADC_TX_MAX < GdData.AdcDataTxLed[i][j]))
			{
				GdData.ErrorTxLed[i] |= 1<<j;
				GdData.Error |= GD_ERROR_TX_LED;
			}
		}
	}
	for (uint8_t i=0; i<GD_WHEEL_COUNT; i++)
	{
		if (GdData.AdcDataRxLedOff[i] > GD_ADC_RX_ERROR)
		{
			GdData.ErrorRxLed |= 1<<i;
			GdData.Error |= GD_ERROR_RX_LED;
		}
	}
}

static void GdAdcToLogic(void)
{
	for (uint8_t i=0; i<GD_WHEEL_COUNT; i++)
	{
		for (uint8_t j=0; j<GD_LED_COUNT_PER_WHEEL; j++)
		{
			//X
			if (GdData.AdcDataRxLedOn[i][j] > GD_ADC_RX_THRESHOLD)
			{
				GdData.LogicDataX[i] |= 1<<j;
			}
		}
	}
}


/*
字轮数据转换解码成读数
*/
static void GdLogicToHex(void)
{
  for (uint8_t i=0; i<GD_WHEEL_COUNT; i++)
  {
	  if ((i&0X01) == 0)
	  {
			  //X
			  GdData.HexDataX[i] = GD_LOGIC_TABLE_0_2_X[GdData.LogicDataX[i]&0X1F];
	  }
	  else
	  {
			  //X
			  GdData.HexDataX[i] = GD_LOGIC_TABLE_1_3_X[GdData.LogicDataX[i]&0X1F];
	  }
	  if ((GdData.HexDataX[i]&0X0A) == 0X0A)
	  {
			  GdData.Error |= GD_ERROR_ADC;
	  }
  }
}

static void GdHexToBcd(void)
{
	//X
	uint8_t HexDataX[GD_WHEEL_COUNT];
	
	memcpy(HexDataX, GdData.HexDataX, GD_WHEEL_COUNT);
	
	for (int8_t i=(GD_WHEEL_COUNT-1); i>0; i--)
	{
		if ((HexDataX[i]&0XF0) == GD_DATA_N)
		{
			if (HexDataX[i-1] == GD_DATA_9P)
			{
				HexDataX[i-1] = GD_DATA_0N;
			}
		}
		else if ((HexDataX[i]&0XF0) == GD_DATA_P)
		{
			if (HexDataX[i-1] == GD_DATA_0N)
			{
				HexDataX[i-1] = GD_DATA_9P;
			}
			else
			{
				int8_t j;
				for (j=(i-1); j>=0; j--)
				{
					if ((HexDataX[j] != GD_DATA_0N)
					&&(HexDataX[j] != GD_DATA_0O)
					&&(HexDataX[j] != GD_DATA_9O)
					&&(HexDataX[j] != GD_DATA_9P))
					{
						break;
					}
				}
				if (j < 0)
				{
					HexDataX[i-1] = GD_DATA_9P;
				}
			}
		}
		GdData.BcdDataX[i] = HexDataX[i]&0X0F;
	}
	GdData.BcdDataX[0] = HexDataX[0]&0X0F;
	for (int8_t i = (GD_WHEEL_COUNT-1); i>= 0; i--)
	{
		GdData.DataX = GdData.DataX*10 + GdData.BcdDataX[i];
	}
}


//HEX:9999m3
// -1 读数失败
//  1 读数成功,返回真实值
int32_t GdGetVolumeData(void)
{
	GdGetAdc();
	GdAdcToLogic();
	GdLogicToHex();
	GdHexToBcd();
	
	if(GdData.Error)
	{		
		return  (-1);  /*返回-1，应用处理上一次的正确的值*/
	}
	return GdData.DataX;;	
}


